package z_painter;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;

import javax.swing.JColorChooser;


public class MyPainter extends Frame implements ActionListener, ItemListener {

	private static final long serialVersionUID = 1L;
	String fileName= "painter.dat";
	MenuBar mb = new MenuBar();  //  @jve:decl-index=0:

	
	Menu fileMenu = new Menu("파일");  
	Menu figureMenu = new Menu("Figure");  //  @jve:decl-index=0:
	Menu colorMenu = new Menu("Color");  //  @jve:decl-index=0:
	Menu lineMenu = new Menu("Line Style");  //  @jve:decl-index=0:
	
	// 파일 메뉴 아이템
	MenuItem fileOpen = new MenuItem("Open");  //  @jve:decl-index=0:
	MenuItem fileSave = new MenuItem("Save");  //  @jve:decl-index=0:
	MenuItem newFile = new MenuItem("Save as");  //  @jve:decl-index=0:
	
	// 도형 메뉴 아이템
	CheckboxMenuItem lineM = new CheckboxMenuItem("Line");  //  @jve:decl-index=0:
	CheckboxMenuItem ovalM = new CheckboxMenuItem("Oval");  //  @jve:decl-index=0:
	CheckboxMenuItem rectM = new CheckboxMenuItem("Rect");  //  @jve:decl-index=0:
	CheckboxMenuItem penM = new CheckboxMenuItem("Pen");  //  @jve:decl-index=0:
	CheckboxMenuItem fillOvalM = new CheckboxMenuItem("Oval(fill)");  //  @jve:decl-index=0:
	CheckboxMenuItem fillRectM = new CheckboxMenuItem("Rect(fill)");  //  @jve:decl-index=0:
	
	//색상
	CheckboxMenuItem blackM = new CheckboxMenuItem("black");  //  @jve:decl-index=0:
	CheckboxMenuItem whiteM = new CheckboxMenuItem("while");
	CheckboxMenuItem blueM = new CheckboxMenuItem("blue");  //  @jve:decl-index=0:
	CheckboxMenuItem redM = new CheckboxMenuItem("red");  //  @jve:decl-index=0:
	CheckboxMenuItem greenM = new CheckboxMenuItem("green");  //  @jve:decl-index=0:
	CheckboxMenuItem moreM = new CheckboxMenuItem("More...");  //  @jve:decl-index=0:
	
	// 선의 유형
	CheckboxMenuItem solidM = new CheckboxMenuItem("solid");  //  @jve:decl-index=0:
	CheckboxMenuItem dotM = new CheckboxMenuItem("dot");  //  @jve:decl-index=0:
	MenuItem lineWidthM = new MenuItem("line weight");  //  @jve:decl-index=0:
	
	// 현재 상태를 저장할 멤버변수
	int type=1; // 도형의 종류 1=선, 2=원, 3=사각, 4=펜
	boolean fill=false; // 채우기 true=fill, false=draw
	Color color= new Color(0,0,0); // 도형의 색상  //  @jve:decl-index=0:
	int style=1; // 선의 유형 1=실선, 2=점섬, 
	int weight=10; // 선의 굵기
	int x, y; // 도형의 좌표
	int w,h; // 도형의 크기
	Vector vx=new Vector(100);  //  @jve:decl-index=0:
	Vector vy= new Vector(100); // 펜의 좌표  //  @jve:decl-index=0:
	Vector allFigure = new Vector(50); // 그려진 도형 저장.
	
	int ex, ey;

	Graphics g;
	
	// 선의 스타일
	BasicStroke bs;  //  @jve:decl-index=0:
	Graphics2D gg;
	float dash[] = { 2.f, 1f};
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		MyPainter mp = new MyPainter();
	}

	/**
	 * This is the default constructor
	 */
	public MyPainter() {
		super();
		makeMenu();
		initialize();
		setVisible(true);
		g = this.getGraphics();
		stroke();

	}
	
	public void makeMenu(){
		this.setMenuBar(mb);
		
		mb.add(fileMenu);
		mb.add(figureMenu);
		mb.add(colorMenu);
		mb.add(lineMenu);
		
		fileMenu.add(fileOpen); fileOpen.addActionListener(this);
		fileMenu.add(fileSave); fileSave.addActionListener(this);
		fileMenu.add(newFile);newFile.addActionListener(this);
		
		figureMenu.add(lineM);lineM.addItemListener(this);
		figureMenu.add(ovalM);ovalM.addItemListener(this);
		figureMenu.add(rectM);rectM.addItemListener(this);
		figureMenu.add(penM);penM.addItemListener(this);
		
		figureMenu.add(fillOvalM);fillOvalM.addItemListener(this);
		figureMenu.add(fillRectM);fillRectM.addItemListener(this);
		
		
		colorMenu.add(blackM);blackM.addItemListener(this);
		colorMenu.add(whiteM);whiteM.addItemListener(this);
		colorMenu.add(redM);redM.addItemListener(this);
		colorMenu.add(greenM);greenM.addItemListener(this);
		colorMenu.add(blueM);blueM.addItemListener(this);
		colorMenu.add(moreM);moreM.addItemListener(this);
		
		lineMenu.add(solidM);solidM.addItemListener(this);
		lineMenu.add(dotM);dotM.addItemListener(this);
		lineMenu.add(lineWidthM);lineWidthM.addActionListener(this);
		
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setSize(736, 460);
		this.setTitle("MyPainter - 한국직업훈련센터");

		this.addWindowListener(new java.awt.event.WindowAdapter() {
			@Override
			public void windowClosing(java.awt.event.WindowEvent e) {
				System.exit(0);
			}
		});

		this.addWindowListener(new java.awt.event.WindowAdapter() {
			@Override
			public void windowDeiconified(java.awt.event.WindowEvent e) {
				repaint();
			}
		});
		
		
		this.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
			@Override
			public void mouseDragged(java.awt.event.MouseEvent e) {
				g.setXORMode(new Color(255,255,255));
				myDraw();
				
				ex = e.getX();
				ey = e.getY();
				
				myDraw();
			}
		});
		this.addMouseListener(new java.awt.event.MouseAdapter() {   
			@Override
			public void mouseReleased(java.awt.event.MouseEvent e) {    
				g.setPaintMode();
				myDraw();
				Data d = new Data();
				d.color = color;
				d.h = h;
				d.style = style;
				d.type = type;
				d.vx = vx;
				d.vy = vy;
				d.w = w;
				d.weight = weight;
				d.x = x;
				d.y = y;
				d.ex = ex;
				d.ey = ey;
				
				allFigure.add(d);
				
				if(type==4){
					vx = new Vector(100);
					vy = new Vector(100);
				}
			}
			@Override
			public void mousePressed(java.awt.event.MouseEvent e) {
				x = e.getX();
				y = e.getY();
				
				ex = x;
				ey = y;
				g.setXORMode(new Color(255,255,255));
				myDraw();
			}
		});
		this.addKeyListener(new java.awt.event.KeyAdapter() {
			@Override
			public void keyPressed(java.awt.event.KeyEvent e) {
				
				String str = KeyEvent.getKeyModifiersText(e.getModifiers());
				if( str.equals(str) && e.getKeyCode() == KeyEvent.VK_Z){
					int cnt = allFigure.size();
					if( cnt >0){
						allFigure.remove(cnt-1);
						repaint();
					}
				}
				
				
				
			}
		});
	}
	
	@Override
	public void paint(Graphics g){

		if( allFigure.size() == 0 ) return;
		for(int i=0 ; i< allFigure.size(); i++){
			Data d = (Data)allFigure.get(i);
			
			// 선의 스타일
			if( d.style == 1){
				float dash[] ={d.weight, 0f};
				bs = new BasicStroke(d.weight, 0, BasicStroke.JOIN_MITER, 1.0f, dash,0);
				gg = (Graphics2D)g;
				gg.setStroke(bs);
				
			}else{
				float dash[] ={d.weight, d.weight};
				bs = new BasicStroke(d.weight, 0, BasicStroke.JOIN_MITER, 1.0f, dash,0);
				gg = (Graphics2D)g;
				gg.setStroke(bs);
				
			}

			g.setColor(d.color);
			int x1=0, y1=0, w=0, h=0;
			
			if(d.x < d.ex) {x1 = d.x; w = d.ex-d.x;}
			if(d.x > d.ex) {x1 = d.ex; w = d.x-d.ex;}
			if(d.y < d.ey) {y1 = d.y; h = d.ey-d.y;}
			if(d.y > d.ey) {y1 = d.ey; h=d.y-d.ey;}

			if( d.type == 1) g.drawLine(d.x, d.y, d.ex,d.ey);
			if( d.type == 2) g.drawOval(x1, y1, w,h);
			if( d.type == 3) g.drawRect(x1, y1, w,h);
			
			if(d.type == 5) g.fillOval(x1, y1, w,h);
			if(d.type == 6) g.fillRect(x1, y1, w,h);
			
			if(d.type==4){
				int sx=0, sy=0 ;
				int sx2=0, sy2=0;
				sx = (Integer)d.vx.get(0);
				sy = (Integer)d.vy.get(0);
				
				for(int j=1 ; j<d.vx.size(); j++){
					sx2 = (Integer)d.vx.get(j);
					sy2 = (Integer)d.vy.get(j);

					g.drawLine(sx, sy, sx2, sy2);
					sx = sx2;
					sy = sy2;
				}
				
			}
			
		}
		
	}
	
	public void myDraw(){
		g.setColor(color);
		int x1=0, y1=0, w=0, h=0;
		
		if(x < ex) {x1 = x; w = ex-x;}
		if(x > ex) {x1 = ex; w = x-ex;}
		if(y < ey) {y1 = y; h = ey-y;}
		if(y > ey) {y1 = ey; h=y-ey;}

		if( type == 1) g.drawLine(x, y, ex,ey);
		if( type == 2) g.drawOval(x1, y1, w,h);
		if( type == 3) g.drawRect(x1, y1, w,h);
		if( type == 4) {
			g.setPaintMode();
			g.drawLine(x,y, ex, ey);
			// 점의 좌표를 벡터 vx, vy 에 저장
			vx.add(x);
			vy.add(y);
			// -------------------------------
			x=ex;
			y=ey;		
		}
		
		if(type == 5) g.fillOval(x1, y1, w,h);
		if(type == 6) g.fillRect(x1, y1, w,h);
		
	}
	

	public void stroke(){
		if( style == 1){
			float dash[] ={weight, 0f};
			bs = new BasicStroke(weight, 0, BasicStroke.JOIN_MITER, 1.0f, dash,0);
			gg = (Graphics2D)g;
			gg.setStroke(bs);
			
		}else{
			float dash[] ={weight, weight};
			bs = new BasicStroke(weight, 0, BasicStroke.JOIN_MITER, 1.0f, dash,0);
			gg = (Graphics2D)g;
			gg.setStroke(bs);
			
		}
	}
	
	// ActionListener method
	@Override
	public void actionPerformed(ActionEvent e){
		if( e.getSource() == lineWidthM){
			MyDialog md = new MyDialog(this);	
		}
		
		if( e.getSource() == fileOpen){
			File file=null;
			try{
				// 0) FileDialog 
				FileDialog fd = new FileDialog(this,"파일 읽기", FileDialog.LOAD);
				fd.setVisible(true);
				fileName=fd.getFile();
				try{
					// 1) File 객체 생성
					file =  new File(fileName);
					if( !file.exists() ) return;
				}catch(Exception ex){}
				
				// 2) 스크림 생성
				FileInputStream fis = new FileInputStream(file);
				BufferedInputStream bis = new BufferedInputStream(fis);
				ObjectInputStream ois = null;
				
				try{
					ois = new ObjectInputStream(bis);
				}catch(Exception ex){
					return;
				}
				allFigure.removeAllElements();
				allFigure.trimToSize();
				allFigure = (Vector)ois.readObject();
				
				// 4) 스트림 닫기
				ois.close();
				bis.close();
				fis.close();
				
				repaint();
			}catch(Exception ex){
				ex.printStackTrace();
			}
			
		}
		
		if( e.getSource() ==fileSave){
			try{
				// 1) File 객체 생성
				File file = new File(fileName);
				
				// 2) OutputStream 생성
				FileOutputStream fos = new FileOutputStream(file,false);
				BufferedOutputStream bos = new BufferedOutputStream(fos);
				ObjectOutputStream oos = new ObjectOutputStream(bos);
				allFigure.trimToSize();
				oos.writeObject(allFigure);
				oos.flush();
				
				// 4) 스트림 close()
				oos.close();
				bos.close();
				fos.close();
			}catch(Exception ex){}
	
		}
		
		if(e.getSource() == newFile){
			File file = null;
			try{
				// 0) FileDialog 
				FileDialog fd = new FileDialog(this,"새파일 저장", FileDialog.SAVE);
				fd.setVisible(true);
				fileName = fd.getFile();
				try{
					// 1) File 객체 생성
					file = new File(fileName);
					if( file.exists() ) return;
				}catch(Exception ex){}
				
				// 2) OutputStream 생성
				FileOutputStream fos = new FileOutputStream(file,false);
				BufferedOutputStream bos = new BufferedOutputStream(fos);
				ObjectOutputStream oos = new ObjectOutputStream(bos);
				allFigure.trimToSize();
				oos.writeObject(allFigure);
				oos.flush();
				
				// 4) 스트림 close()
				oos.close();
				bos.close();
				fos.close();
			}catch(Exception ex){}
			
		}
		
	}


	
	// ItemListener method
	@Override
	public void itemStateChanged(ItemEvent e){
		CheckboxMenuItem item = (CheckboxMenuItem)e.getSource();
		Menu m = (Menu)item.getParent();

		// 도형메뉴의 on/off
		if( m == figureMenu){
			lineM.setState(false);
			ovalM.setState(false);
			rectM.setState(false);
			penM.setState(false);
			fillOvalM.setState(false);
			fillRectM.setState(false);
			
			item.setState(true);
			if(item == lineM) type = 1;
			if(item == ovalM) type = 2;
			if(item == rectM) type = 3;
			if(item == penM) type = 4;
			if(item == fillOvalM) type = 5;
			if(item == fillRectM) type = 6;
		
		}
		// 컬러메뉴의 on/off
		if( m == colorMenu){
			blackM.setState(false);
			whiteM.setState(false);
			redM.setState(false);
			greenM.setState(false);
			blueM.setState(false);
			moreM.setState(false);

			item.setState(true);
			if ( item == blackM ) color = new Color(0,0,0);
			if( item == whiteM) color = new Color(255,255,255);
			if( item== redM) color = new Color(255,0,0);
			if( item == greenM) color = new Color(0,255,0);
			if( item == blueM) color = new Color(0,0,255);
			if( item == moreM) {
				javax.swing.JColorChooser cc = new javax.swing.JColorChooser(color);
				color = JColorChooser.showDialog(this,"색상", color); 
			}
			
		}
	
		// 선 종류 메뉴의 on/off
		if ( m == lineMenu){
			solidM.setState(false);
			dotM.setState(false);
			
			item.setState(true);

			// 선의 스타일 정의
			if( item == solidM){
				float dash[] ={weight, 0f};
				bs = new BasicStroke(weight, 0, BasicStroke.JOIN_MITER, 1.0f, dash,0);
				gg = (Graphics2D)g;
				gg.setStroke(bs);
				style = 1; // 실선
			}
			
			if(item == dotM){
				float dash[] ={weight, weight};
				bs = new BasicStroke(weight, 0, BasicStroke.JOIN_MITER, 1.0f, dash,0);
				gg = (Graphics2D)g;
				gg.setStroke(bs);
				style = 2; // 점선
			}
		}
	}
	
	
}  //  @jve:decl-index=0:visual-constraint="26,48"
